
import Singleton from "../../../framework/bo/Singleton";
import ClientContext from "../../global/ClientContext";
import NetData from "../../../framework/net/NetData";
import { proto } from "../../../../../tools/proto/protos";
import SendData from "../../../framework/net/codec/SendData";
import { Constant, ServerApi } from "../../../Enum/Enum";
import { UIManager } from "../../../framework/manager/uiManager";

/**
 * 玩家账户服务，实现账户注册登陆等功能
 */
export class AccountService extends Singleton {
    public static get Instance(): AccountService {
        return super.GetInstance<AccountService>();
    }

    /**
     * 用户注册
     * @param account 用户名
     * @param password 密码
     */
    public async register(account: string, password: string): Promise<proto.UserInfoProto> {// 注册失败返回错误数据
        console.log(`注册用户`);
        let proto: proto.StrStrProto = NetData.createProtoInstance("StrStrProto");
        proto.str1 = account;
        proto.str2 = password;
        let sendData = new SendData(proto, ServerApi.Register);
        let res = await ClientContext.Instance.hallSocket.sendSync(sendData);// 向服务器注册接口发送数据注册
        // console.log(res);
        if (res.hasOwnProperty('errorCode')) {
            console.log("注册错误码", res);
            UIManager.instance.showTips(res.msg, null, Constant.TIPS_ANI_NAME.tips2aniTop);
            return null;
        } else {
            const userInfoProto: proto.UserInfoProto = res;
            // ContextClient.Instance.UserInfo = userInfoProto;
            console.log("收到注册结果", userInfoProto);
            return userInfoProto;
            // console.log(ContextClient.Instance.userInfo);
            // StorageManager.instance.setGlobalData(Constant.LOCAL_CACHE.UserInfo, ContextClient.Instance.userInfo); 在上下文调用
            // this.updateUserInfoState();// 弃用
        };
    }

    public async getUserInfo(account: string, password: string): Promise<proto.UserInfoProto> {
        console.log('获取用户信息');
        let proto: proto.StrStrProto = NetData.createProtoInstance("StrStrProto");
        proto.str1 = account;
        proto.str2 = password;
        let sendData = new SendData(proto, ServerApi.getUserInfo);
        let res = await ClientContext.Instance.hallSocket.sendSync(sendData);// 向服务器注册接口发送数据注册
        if (res.hasOwnProperty('errorCode')) {
            console.error("错误码", res);
            UIManager.instance.showTips(res.msg, null, Constant.TIPS_ANI_NAME.tips2aniTop);
            return null;
        } else {
            const userInfoProto: proto.UserInfoProto = res;
            console.log("收到注册结果", userInfoProto);
            return userInfoProto;
        };
    }
    /**用户登陆 */
    public async login(account: string, password: string, areaId: number, platformId: string): Promise<any> {// 保存userInfo并返回登陆成功
        console.log("登陆用户");
        const userInfo = ClientContext.Instance.userInfo;
        let proto: proto.StrStrIntStrProto = NetData.createProtoInstance("StrStrIntStrProto"); // 调用服务器登陆接口
        proto.s1 = account;
        proto.s2 = password;
        proto.i3 = areaId;
        proto.s4 = platformId;
        let sendData = new SendData(proto, ServerApi.Login);
        let res = await ClientContext.Instance.hallSocket.sendSync(sendData);
        if (res.hasOwnProperty('errorCode')) {
            console.error("错误码", res);
            UIManager.instance.showTips(res.msg, null, Constant.TIPS_ANI_NAME.tips2aniTop);
            return null;
        } else {
            return new Promise((resolve) => {
                console.log("登陆成功", res);
                let roleInfo: proto.RoleInfoProto = res.roleInfo;
                ClientContext.Instance.roleInfo = roleInfo; //  接受并处理登陆接口的消息
                resolve(res);
            });
        }
    }

    /**
     *  从登陆服务器获取区服信息
     */
    public async getServerInfos(): Promise<boolean> {
        console.log(`获取区服信息`);
        let proto: proto.EmptyProto = NetData.createProtoInstance("EmptyProto");
        let sendData = new SendData(proto, ServerApi.ServerInfos);
        let res = await ClientContext.Instance.hallSocket.sendSync(sendData);
        if (res.hasOwnProperty('errorCode')) {
            console.log("错误码", res);
            UIManager.instance.showTips(res.msg, null, Constant.TIPS_ANI_NAME.tips2aniTop);
            return false;
        } else {
            console.log("收到结果", res);
            const serverInfos0 = JSON.parse((<proto.StringProto>res).str);
            // console.log("区服信息", ContextClient.Instance.serverInfos[0]);
            const serverInfos = serverInfos0.map((serverInfo) => {
                return {
                    ...serverInfo,
                    areaInfos: serverInfo.areaInfos.map((areaInfo) => {
                        return {
                            ...areaInfo,
                            serverId: serverInfo.serverId
                        };
                    })
                };
            });
            ClientContext.Instance.ServerInfos = serverInfos;
        }
        return true;
    }

    /**
     * 更用户状态信息（目前只是初始化区服使用）
     * @deprecated
     */
    private updateUserInfoState() {
        let state = ClientContext.Instance.userInfo.state;
        if (state == undefined) {// 直接给玩家指定选区
            const serverInfos = ClientContext.Instance.ServerInfos; //将初始化区服写进状态
            const serverInfosjson = JSON.stringify(serverInfos);

            let jsonInfo = JSON.parse(serverInfosjson);
            jsonInfo.splice(1, jsonInfo.length - 1); // 删除属性 从索引 1 开始删除，删除剩余的元素
            jsonInfo[0].areaInfos.splice(1, jsonInfo[0].areaInfos.ljsonInfo1);// 删除其他 areaInfos 元素
            // 添加 roleId 属性到 areaInfos[0]
            jsonInfo[0].areaInfos[0].roleId = -1;

            // 如果需要将修改后的 JSON 对象转换回原始对象，可以使用以下方法：
            const newServerInfos = JSON.parse(JSON.stringify(jsonInfo));
            // 添加新的 serverInfos 键
            const newState = {
                serverInfos: newServerInfos
            };
            const newStateStr = JSON.stringify(newState);
            ClientContext.Instance.userInfo.state = newStateStr
            let proto: proto.StrStrProto = NetData.createProtoInstance("StrStrProto");
            proto.str1 = ClientContext.Instance.userInfo.account + ',' + ClientContext.Instance.userInfo.password + ',' + ClientContext.Instance.userInfo.platformId;
            proto.str2 = newStateStr;
            let sendData = new SendData(proto, ServerApi.updateUserInfoState);
            ClientContext.Instance.hallSocket.send(sendData, (res: proto.BoolProto) => {
                if (res.bol) {
                    console.log("修改更新state成功");
                } else {
                    console.log("修改更新state失败");
                }
            });
        } else {
            console.log("state", state);
        }
    }
    /**
     * @deprecated
     */
    public async selectServerAndArea(account: string, password: string, serverId: number, areaId: number, platformId: string) {
        let proto: proto.StrIntIntProto = NetData.createProtoInstance("StrIntIntProto");
        proto.str1 = account + ',' + password + ',' + platformId;
        proto.int2 = serverId;
        proto.int3 = areaId;
        let sendData = new SendData(proto, ServerApi.selectServerAndArea);
        let res = await ClientContext.Instance.hallSocket.sendSync(sendData);
        if (res.hasOwnProperty('errorCode')) {
            console.log("错误码", res);
            UIManager.instance.showTips(res.msg, null, Constant.TIPS_ANI_NAME.tips2aniTop);
            return null;
        } else {
            return res;
        }
    }


}